﻿/*
RSuite Service proxy
====================

Version: 1.0

Requisites: jQuery

Features: act as proxy for local calls, remote calls and ajax calls

Usage:
- `Service.local(options)` to make local calls (through web-browser control)
- `Service.remote(options)` to make remote calls (to local WCF Service or real web service)
- `options` has:
    - `method`: name of the method to call
    - `params`: object contains parameters
    - `complete`: function(data) to be called after completion
    - `update`: function(data) to be called when progress updates
    - `error`: function(data) to e called if error occurs

Sample:
    
    Services.local({
        method: 'open',
        params: 'test.txt',
        complete: function(data) {
            alert(data);
        },
        error: function(data) {
            alert(data.message);
        }
    });

*/
var Services = {
    localSupport: typeof Awesomium !== 'undefined',
    local: function (obj) {
        if (!this.localSupport) {
            alert('Local call is not supported!!!');
            if (typeof obj.error !== 'undefined') {
                obj.error();
            }
            return;
        }

        var defaultOptions = {
            method: null,
            params: null,
            complete: null,
            update: null,
            error: null,
            target: null
        };
        var options = $.extend({}, defaultOptions, obj);
        var id = Async.regist(options.target, options.complete, options.update, options.error);
        Awesomium.InvokeMethod(options.method, JSON.stringify(options.params), id);

        return id;
    },
    remote: function (method, params, options) {
        options.data = {
            method: method,
            parameters: JSON.stringify(params)
        };
        options = $.extend({}, { success: null, error: null }, options);

        if (options.success) {
            var success = options.success;
            options.success = function (data) {
                if (typeof data.status !== 'undefined') {
                    if (options.error) {
                        options.error(data);
                    }
                }
                else {
                    success(data);
                }
            }
        }

        options.dataType = 'json';
        $.ajax(options);
    }
};

/* Asynchronous manager */
function AsyncManager() {
    this.queue = [];
    this.id = 0;
}
AsyncManager.prototype = {
    popTask: function (id) {
        for (var i = 0; i < this.queue.length; i++) {
            if (this.queue[i].id == id) {
                var task = this.queue[i];
                this.queue.splice(i, 1);
                return task;
            }
        }
        return null;
    },
    getTask: function (id) {
        for (var i = 0; i < this.queue.length; i++) {
            if (this.queue[i].id == id) {
                return this.queue[i];
            }
        }
        return null;
    },
    finishTask: function (id, data) {
        var task = this.popTask(id);
        if (task) {
            //alert(data);
            var obj = JSON.parse(data);
            if (typeof obj.status !== 'undefined') {
                if (task.error) {
                    task.error.call(task.obj, obj);
                }
            }
            else if (task.complete) {
                task.complete.call(task.obj, obj);
            }
        }
    },
    updateTask: function (id, data) {
        var task = this.getTask(id);
        if (task && task.update) {
            var obj = JSON.parse(data);
            task.update.call(task.obj, obj);
        }
    },
    regist: function (obj, complete, update, error) {
        if (!complete && !update && !error) {
            return -1;
        }

        var id = this.id++;
        this.queue.push({
            id: id,
            obj: obj,
            complete: complete,
            update: update,
            error: error
        });
        return id;
    }
};
var Async = new AsyncManager();